package com.node.tools.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.node.tools.mapper.SecondNodeMapper;
import com.node.tools.service.ISecondNodeService;
import com.node.tools.utils.HttpUtil;
import com.node.tools.vo.DataHaiLi;
import lombok.SneakyThrows;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.swing.*;
import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @Created IntelliJ IDEA.
 * @Author XYoK
 * @Description  码云所有方法接口
 * @Setting Editor | File and Code Templates.
 */
@Service
@Component
public class SecondNodeServiceImpl extends ServiceImpl<SecondNodeMapper, DataHaiLi> implements ISecondNodeService {
    private static Logger logger = LoggerFactory.getLogger(SecondNodeServiceImpl.class);

    public static final String enc = "UTF-8";

    @Autowired
    private SecondNodeMapper secondNodeMapper;

    @Value("${secondNode.getUrl}")
    private String getUrl;

    @Value("${secondNode.getUserName}")
    private String getUserName;

    @Value("${secondNode.getPassWord}")
    private String getPassWord;

    @Value("${secondNode.prefix}")
    private String prefix;

    public static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式

    /***
     * 标识注册流程
     * @throws Exception
     */
    public void saveData() {
        List<DataHaiLi> query = secondNodeMapper.saveData();
        System.out.println(query.size());
        Set<String> set = new HashSet<>();
        List<DataHaiLi> list = new ArrayList<>();
        Integer product = 0;
        Integer batchId = 0;
        try {
            String tokenCode = getToken();//获取Token
            String name = userInfo(tokenCode);//查询用户信息
            for (DataHaiLi demo : query) {
                boolean contains = set.contains(demo.getOrderCode());
                if (contains) {
                    logger.error("此编号已注册标识！" + JSON.toJSONString(demo));
                    continue;
                } else {
                    list.add(demo);
                    set.add(demo.getOrderCode());//把编号存入set,为创建重复标识作判断
                    //todo 此处多线程
                    product = productList(tokenCode, demo);//添加产品基础信息
                    if (product == null){ continue; }
                    batchId = productBatchList(product, tokenCode, name, demo);//批次添加
                }
            }
            dealWith(product, batchId, tokenCode, list);
        } catch (Exception e) {
            logger.error("调用二级节点方法错误 -> {}", e);
        }
    }

    /***
     * 数据处理
     * @param product
     * @param batchId
     * @param tokenCode
     * @param list
     */
    public void  dealWith(Integer product, Integer batchId, String tokenCode, List<DataHaiLi> list){
        //todo 应为1000
        if (list.size() < 10) {
            Map<String, Object> map = postDefineSave(product, tokenCode,list);//根据唯一码生成标识
            postDefineUpdate(product, batchId, map, tokenCode);//标识码更新
            //codeInfo(map, tokenCode);//标识解析
        } else {
            int len = 10;
            int size = list.size();
            int count = (size + len - 1) / len;
            for (int i = 0; i < count; i++) {
                List<DataHaiLi> subListOK = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
                Map<String, Object> map = postDefineSave(product, tokenCode,subListOK);//根据唯一码生成标识
                postDefineUpdate(product, batchId, map, tokenCode);//标识码更新
                //codeInfo(map, tokenCode);//标识解析
                int j = i+1;
                System.out.println("批次处理,第"+j+"批");
            }
        }
    }

    /***
     * 获取token
     */
    @SneakyThrows
    public String getToken() {
        Map<String, String> headers = new HashMap<>();
        List<BasicNameValuePair> list = new ArrayList<>();
        String url = getUrl + "/openApi/v1/user/login";
        headers.put("Content-type", "application/x-www-form-urlencoded");
        BasicNameValuePair userName = new BasicNameValuePair("username", getUserName);
        BasicNameValuePair password = new BasicNameValuePair("password", getPassWord);
        list.add(userName);list.add(password);
        String token = "";
        try {
            String param = HttpUtil.sslPost(url, headers, list);
            token = JSON.parseObject(param).getJSONObject("data").getString("token");
            logger.info("Token -> " + token);
        } catch (Exception e) {
            logger.error("Token获取失败！-> " + e);
        }
        return token;
    }

    /***
     * 获取用户信息
     * @param tokenCode
     * @return
     */
    @SneakyThrows
    public String userInfo(String tokenCode){
        String url = getUrl + "/openApi/v1/user/info";
        HashMap<String, Object> hashMap = new HashMap<>();hashMap.put("","");
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-type", "application/x-www-form-urlencoded");
        headers.put("Authorization", "Bearer " + tokenCode);
        String name = " ";
        try {
            String s = HttpUtil.sslGet(url, headers, hashMap);
            name = JSON.parseObject(s).getJSONObject("data").getString("name");
            logger.info("用户-> " + JSON.parseObject(s));
        }catch (Exception e){
            logger.error("用户信息获取失败！-> " + e);
        }
        return name;
    }

    /***
     * 添加产品信息
     * @param tokenCode
     * @param demo
     * @return
     */
    public Integer productList(String tokenCode, DataHaiLi demo) {
        JSONObject object = new JSONObject();
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("attrNameCn", "设备类型名称");
        hashMap.put("attrNameEn", "deviceCategoryName");
        hashMap.put("attrIndex", 1);
        hashMap.put("attrValue", demo.getDeviceCategoryName());
        hashMap.put("attrType", 10);
        ArrayList<Map> productAttrs = new ArrayList<>();
        productAttrs.add(hashMap);
        ArrayList<Map> productImgList = new ArrayList<>();
        object.put("productNo",demo.getOrderId());//产品编号
        object.put("category",11663);//产品分类
        //object.put("productName",demo.getLaundryName() + demo.getOrderCode());//产品名称
        object.put("productName","HaiLi:" + demo.getId());//产品名称
        object.put("remark","海狸订单数据");//备注
        object.put("price",demo.getTotalPrice());//价格
        object.put("barCode",demo.getOrderCode());//条码
        object.put("prefix",prefix);//前缀
        object.put("productAttrs",productAttrs);//新加属性
        object.put("productImgList",productImgList);
        String jsonString = JSON.toJSONString(object);
        String addProductUrl = getUrl + "/openApi/v1/product/addProduct";
        Integer productId = null;
        try {
            String s = HttpUtil.sslJsonPost(addProductUrl, jsonString, enc, tokenCode);
            String code = JSON.parseObject(s).getString("code");
            if ("200".equals(code)){
                productId = JSON.parseObject(s).getJSONObject("data").getInteger("id");
                logger.info("添加产品信息->", JSON.parseObject(s).getJSONObject("data"));
                return productId;
            }
        } catch (Exception e) {
            logger.error("添加产品信息失败！,", e);
        }
        return productId;
    }

    /***
     * 批次添加
     * @param productId
     */
    @SneakyThrows
    public Integer productBatchList(Integer productId, String tokenCode, String name, DataHaiLi demo){
        Integer batchId = null;
        Long format = System.currentTimeMillis();
        String substring = format.toString().substring(7, 13);
        Map<String, String> header = new HashMap<>();
        header.put("Content-type", "application/x-www-form-urlencoded");
        header.put("Authorization","Bearer " + tokenCode);
        List<BasicNameValuePair> list1 = new ArrayList<>();
        BasicNameValuePair batchNo = new BasicNameValuePair("batchNo", demo.getOrderId() + substring);
        BasicNameValuePair batchTitle = new BasicNameValuePair("batchTitle", demo.getLaundryName() + demo.getOrderCode());
        BasicNameValuePair productIds = new BasicNameValuePair("productId", String.valueOf(productId));
        BasicNameValuePair batchResponorUser = new BasicNameValuePair("batchResponorUser", name);
        BasicNameValuePair batchDate = new BasicNameValuePair("batchDate", df.format(System.currentTimeMillis()));
        list1.add(batchNo);list1.add(batchTitle);list1.add(productIds);
        list1.add(batchResponorUser);list1.add(batchDate);
        String addUrl = getUrl + "/openApi/v1/productBatch/add";
        try {
            String param1 = HttpUtil.sslPost(addUrl, header, list1);
            batchId = JSON.parseObject(param1).getJSONObject("data").getInteger("id");
            logger.info("批次添加成功！-> 批次编号 {}" + batchId);
        } catch (Exception e) {
            logger.error("批次添加失败！-> " + e);
        }
        return batchId;
    }

    /***
     * 根据唯一码生成标识
     * @param product
     * @param tokenCode
     * @return
     */
    @SneakyThrows
    public Map<String, Object> postDefineSave(Integer product, String tokenCode, List<DataHaiLi> list){
        List<String> dataHaiLis = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            //todo 以后换为orderId
            String orderCode = list.get(i).getOrderCode();
            dataHaiLis.add(orderCode);
        }
        JSONObject jsonObject = new JSONObject();
        JSONObject object = new JSONObject();
        jsonObject.put("definedCodes",dataHaiLis);//码集合
        object.put("productId",product);//产品id
        object.put("generate",jsonObject);//生码参数
        object.put("prefix", prefix);//前缀
        String jsonString = JSON.toJSONString(object);
        String url = getUrl + "/openApi/v1/code/postDefine";
        HashMap<String, Object> hashMap = new HashMap<>();
        try {
            String s = HttpUtil.sslJsonPost(url, jsonString, enc, tokenCode);
            JSONArray data = JSON.parseObject(s).getJSONArray("data");
            logger.info("标识-> " + JSON.parseObject(s));
            for (int i = 0; i < data.size(); i++) {
                String idisCode = data.getJSONObject(i).getString("idisCode");
                String qrCode = data.getJSONObject(i).getString("qrCode");
                hashMap.put(idisCode, qrCode);
            }
        }catch (Exception e){
            logger.error("生成标识失败" + e);
        }
        return hashMap;
    }

    /***
     * 标识码更新
     * @param productId
     * @param batchId
     * @param map
     * @param tokenCode
     */
    @SneakyThrows
    public void postDefineUpdate(Integer productId, Integer batchId, Map<String, Object> map, String tokenCode){
        JSONObject object = new JSONObject();
        Map<String, Object> hashMap = new HashMap<>();
        ArrayList<String> list = new ArrayList<>();
        for (Map.Entry<String, Object> entry : map.entrySet()){ String key = entry.getKey();list.add(key);}
        hashMap.put("batchId",batchId);hashMap.put("hasCheckCode",true);
        object.put("productId",productId);object.put("value",hashMap);object.put("idisCodes",list);
        String params = JSON.toJSONString(object);
        String url = getUrl + "/openApi/v1/code/postDefineUpdate";
        try {
            String s = HttpUtil.sslJsonPost(url, params, enc, tokenCode);
            logger.info("更新成功！->" + JSON.parseObject(s));
        } catch (Exception e) {
            logger.error("调用标识码更新接口失败！,", e);
        }
    }

    /***
     * 标识解析
     * @param map
     * @param tokenCode
     */
    public void codeInfo(Map<String, Object> map, String tokenCode){
        JSONObject object = new JSONObject();
        List<String> list = new ArrayList<>();
        for (Map.Entry<String, Object> entry : map.entrySet()){
            String key = entry.getKey();
            String str = key.substring(0,key.indexOf("/"));
            String str1 = key.substring(str.length()+1, key.length());
            list.add(str1);
        }
        object.put("codes",list);
        String s = JSON.toJSONString(object);
        String url = getUrl + "/openApi/v1/code/codeInfo";
        try {
            String post = HttpUtil.sslJsonPost(url, s, enc, tokenCode);
            logger.info("解析-> " + JSON.parseObject(post));
        }catch (Exception e){
            logger.error("调用标识解析接口失败！,", e);
        }
    }
}

